use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::Display;
use std::str::FromStr;

#[derive(Deserialize)]
#[serde(untagged)]
enum StringOrOther<T> {
    String(String),
    Other(T),
}

/// 将字符串转成其他类型
/// 如果不是字符串，则不做改变
pub fn string_other<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
    T: FromStr + Deserialize<'de>,
    T::Err: Display,
    D: Deserializer<'de>,
{
    match StringOrOther::deserialize(deserializer)? {
        StringOrOther::String(s) => s.parse().map_err(serde::de::Error::custom),
        StringOrOther::Other(n) => Ok(n),
    }
}

/// 将其他类型转成字符串
/// 如果是字符串，则不做改变
pub fn other_string<S, T>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
    T: Display
{
    source.to_string().serialize(serializer)
}
